package com.cz.aop.aspect;

import com.cz.aop.annotation.LabelMethod;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @description label注解的切面
 * @auther chengzhen
 * @date 2022/1/12 11:13
 * Debug the code, info the world!
 */
@Aspect
@Component
//@SuppressWarnings("all")
public class LabelAspect {
    public static final Logger logger = LoggerFactory.getLogger(LabelAspect.class);
    public static final ObjectMapper mapper = new ObjectMapper();

    @Pointcut("@annotation(com.cz.aop.annotation.LabelMethod)")
    public void annotationPointcut() {

    }

    @Around("annotationPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //获取方法注解里面的值
        LabelMethod labelMethod = methodSignature.getMethod().getAnnotation(LabelMethod.class);
        logger.info("注解labelOne value:{}", labelMethod.value());
        //获取方法的入参和名称
        String[] params = methodSignature.getParameterNames();// 获取参数名称
        Object[] args = joinPoint.getArgs();// 获取参数值
        logger.info("params:{} \nargs:{}", mapper.writeValueAsString(params), mapper.writeValueAsString(args));
        return joinPoint.proceed();
    }

    @Before("annotationPointcut()")
    public void beforePointcut(JoinPoint joinPoint) {
        // 此处进入到方法前  可以实现一些业务逻辑
        logger.info("进入annotationPointcut之前... 获取注解上的值如下");
    }

    /**
     * 在切入点return内容之后切入内容（可以用来对处理返回值做一些加工处理）
     * @param joinPoint
     */
    @AfterReturning("annotationPointcut()")
    public void doAfterReturning(JoinPoint joinPoint) {
        logger.info("进入annotationPointcut之后...");
    }

}
